#!/usr/bin/python2.4
#
# Copyright 2009 Google Inc. All Rights Reserved.
"""Merge different RSS feeds into a single feed."""

import logging
import StringIO
import xml.dom
from xml.dom import minidom


def FindChild(root, tag_name):
  """Find the child of the given tag_name in root."""
  for child in root.childNodes:
    if child.nodeType == xml.dom.Node.TEXT_NODE:
      continue
    if hasattr(child, 'tagName'):
      if child.tagName == tag_name:
        return child
      else:
        pass


def MergeFeeds(documents):
  """Merge a list of feeds.

  Args:
    documents: a list of two tuples of (agencyname, RSS text)

  Returns:
    The merged RSS feed.
  """
  from controllers.query import Agency
  impl = minidom.getDOMImplementation()
  doc = impl.createDocument(None, 'rss', None)
  rss = doc.childNodes[0]
  rss.setAttribute('xmlns:georss', 'http://www.georss.org/georss')
  rss.setAttribute('xmlns:atom', 'http://www.w3.org/2005/Atom')
  rss.setAttribute('version', '2.0')
  rss.setAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/')
  rss.setAttribute('xmlns:rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#')
  rss.setAttribute('xmlns:taxo', 'http://purl.org/rss/1.0/modules/taxonomy/')
  rss.setAttribute('xmlns:gml', 'http://www.opengis.net/gml')
  rss.setAttribute('xmlns:mapvisage', 'http://mapvisage.appspot.com/0.1/rss')
  channel = rss.appendChild(doc.createElement('channel'))
  channel.appendChild(doc.createElement('title')).appendChild(
      doc.createTextNode('Merged Fire Information'))
  description = channel.appendChild(doc.createElement('description'))
  description.appendChild(doc.createTextNode(
      'This is a merged view of fire map data from the fire authorities: '
      'Victorian CFA, NSW RFS, South Australian CFS and Tasmanian TFS.'))

  last_updated = {}
  for agency in Agency.all():
    last_updated[agency.agency] = agency.last_updated
    logging.info('found last_updated for %s of %s', agency.agency,
                 agency.last_updated)

  for agency, _ in documents:
    logging.info('looking for %s in %s', agency, str(last_updated.keys()))
    if agency in last_updated:
      agency_node = doc.createElement('mapvisage:agency')
      agency_node.setAttribute('name', agency)
      # flash wants dates in form 'Sun Nov 22 13:00:00 UTC 2009'
      agency_node.setAttribute('last_updated',
                               last_updated.get(agency).strftime(
                                   '%a %b %d %H:%M:%S UTC %Y'))
      channel.appendChild(agency_node)
      logging.info('appending %s to channel', agency_node)

  for agency, rss in documents:
    itemcount = 0
    georss = 0
    logging.info('merging in data from agency %s - %d bytes', agency, len(rss))
    thisdoc = minidom.parseString(rss)
    thisrss = FindChild(thisdoc, 'rss')
    thischannel = FindChild(thisrss, 'channel')
    # extract descriptions
    #thisdesc = FindChild(thischannel, 'description')
    #for i in thisdesc.childNodes:
      #description.appendChild(i)
    for item in thischannel.childNodes:
      if item.nodeType == xml.dom.Node.TEXT_NODE:
        continue
      if item.tagName != 'item':
        continue
      channel.appendChild(item.cloneNode(deep=True))
      itemcount += 1
      if FindChild(item, 'georss:point'):
        georss += 1
    logging.info('merged in %d items from agency %s, %d with geo', itemcount,
                 agency, georss)

  output = StringIO.StringIO()
  doc.writexml(output)
  output = output.getvalue()
  if isinstance(output, unicode):
    output = output.encode('utf-8')

  

  return output
